package math;

public class math
{
    
    private math()
    {
    }
    
    
    public static final double EPSILON = 1.0E-6;
    
    public static final double PI = 3.14159265358979323846;
    
    public static final double E = 2.7182818284590452354;
    
    public static final double REC_RT2 = 0.7071067811865475244;
    
    
    public static int maxi(int a, int b)
    {
        return (a < b) ? b : a;
    }
    
    public static int mini(int a, int b)
    {
        return (a < b) ? a : b;
    }
    
    public static int absi(int a)
    {
        return (a < 0) ? -a : a;
    }
    
    public static int powi(int aBase, int aExp)
    {
        return (int)(0.5 + Math.pow(aBase, aExp));
    }
    
    public static int clampi(int aNum, int aBoundsLo, int aBoundsHi)
    {
        aNum = (aNum < aBoundsLo) ? aBoundsLo : aNum;
        aNum = (aNum > aBoundsHi) ? aBoundsHi : aNum;
        return aNum;
    }
    
    
    public static double rand1f()
    {
        return StrictMath.random();
    }
    
    public static double rsqrt(double aNum)
    {
        double half = 0.5 * aNum;
        long bits = Double.doubleToRawLongBits(aNum);
        bits = 0x5fe6eb50c7b537a9L - (bits >> 1);
        double result = Double.longBitsToDouble(bits);
        result = result * (1.5 - (half * result * result));
        result = result * (1.5 - (half * result * result));
        return result;
    }
    
    public static double clampd(double aNum, double aBoundsLo, double aBoundsHi)
    {
        aNum = (aNum < aBoundsLo) ? aBoundsLo : aNum;
        aNum = (aNum > aBoundsHi) ? aBoundsHi : aNum;
        return aNum;
    }
    
    public static double toRad(double aDeg)
    {
        return (aDeg * math.PI / 180.0);
    }
    
    public static double toDeg(double aRad)
    {
        return (aRad * 180.0 / math.PI);
    }
    
    public static double lerp(double aLo, double aHi, double aInterpTerm)
    {
        return (1.0 - aInterpTerm) * aLo + aInterpTerm * aHi;
    }
    
    public static double invLerp(double aNum, double aLo, double aHi)
    {
        return (aNum - aLo) / (aHi - aLo);
    }
    
    public static double max(double a, double b)
    {
        return (a < b) ? b : a;
    }
    
    public static double min(double a, double b)
    {
        return (a < b) ? a : b;
    }
    
    public static double abs(double a)
    {
        return (a < 0) ? -a : a;
    }
    
    public static double exp(double a)
    {
        return StrictMath.exp(a);
    }
    
    public static double powd(double base, double exp)
    {
        return StrictMath.pow(base, exp);
    }
    
    public static double sqrt(double a)
    {
//        return StrictMath.sqrt(a);
        return 1.0 / math.rsqrt(a);
    }
    
    public static double cos(double rad)
    {
        return StrictMath.cos(rad);
    }
    
    public static double sin(double rad)
    {
        return StrictMath.sin(rad);
    }
    
    public static double tan(double rad)
    {
        return StrictMath.tan(rad);
//        return (rad * (1 + rad * rad * (0.333333333334 + rad * rad * 0.133333333334)));
    }
    
    public static double acos(double a)
    {
        return StrictMath.acos(a);
    }
    
    public static double asin(double a)
    {
        return StrictMath.asin(a);
    }
    
    public static double atan(double y, double x)
    {
        return StrictMath.atan2(y, x);
    }
    
    
}
